package server;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.Properties;

import org.apache.log4j.Logger;

public class WebServerThread implements Runnable {
	private static final Logger log = Logger.getLogger(WebServerThread.class);

	private final Socket client;
	private final Properties properties;

	public WebServerThread(Socket client, Properties properties) {
		this.client = client;
		this.properties = properties;
	}

	public void describeConection(Socket client) {
		InetAddress inet = client.getInetAddress();
		log.info("Accepted connection to [" + inet.getCanonicalHostName() + "] (" + inet.getHostAddress() + ") " + "on port " + client.getPort() + ".");
	}

	@Override
	public void run() {
		describeConection(client);

		InputStream inStream = null;
		OutputStream outStream = null;

		String bufferCommand = null;
		String[] commands = null;
		try {
			/* Open output stream */
			outStream = client.getOutputStream();

			/* Analyze the request from client */
			inStream = client.getInputStream();

			// Get request
			int len = inStream.available();
			while (len > 0) {
				byte[] buffers = new byte[len];
				inStream.read(buffers, 0, len);
				bufferCommand = new String(buffers);
				bufferCommand = bufferCommand.trim();
				commands = bufferCommand.split("[\\s\\n]");

				// Process request
				if(commands.length > 1) {
					// GET request
					if(commands[0].equalsIgnoreCase("GET")) {
						// Send a file to client
						senFileAsRequestGET(commands[1], outStream);
					}
				}

				// Log commands
				log.info("Client request: " + Arrays.toString(commands));
				len = inStream.available();
			}

			inStream.close();
			outStream.close();
		}catch (IOException e) {
			log.error(e.getMessage(), e.getCause());
		}finally {
			try {
				client.close();
			}catch (IOException e) {
				log.error(e.getMessage(), e.getCause());
			}
		}
	}

	private void senFileAsRequestGET(String fileName, OutputStream outStream) throws IOException {
		String rootDir = properties.getProperty("rootDir", System.getProperty("user.dir"));
		File file = new File(rootDir, fileName);

		/* Open default file if file does not exist */
		if(!file.exists() || file.isDirectory()) {
			file = new File(rootDir, properties.getProperty("defaulFile"));
			if(!file.exists()) {
				log.error("File " + file.getAbsolutePath() + "does not exist.");
				return;
			}
		}

		// Open file for reading
		FileInputStream fInput = new FileInputStream(file);
		int len = fInput.available();
		byte[] b = new byte[len];

		// Write byte to output stream
		fInput.read(b, 0, len);
		outStream.write(b);
		outStream.flush();
		fInput.close(); // close file reading

		log.info("Sent file " + file.getName() + " " + len + " byte(s)");
	}
}
